//
//  VC12DynamicAnimator.swift
//  ChapterAll
//
//  Created by Kevin on 2020/5/6.
//  Copyright © 2020 Kevin. All rights reserved.
//

import UIKit

class VC12DynamicAnimator: UIViewController,UICollisionBehaviorDelegate {
    
    lazy var uiRedView = { ()-> UIView in
        let ui = UIView()
        ui.backgroundColor = UIColor.red
        ui.frame = CGRect(x: 70, y: 100, width: 100, height: 100)
        return ui
    }()
    
    lazy var uiBlueView = { ()-> UIView in
        let ui = UIView()
        ui.backgroundColor = UIColor.blue
        ui.frame = CGRect(x: 135, y: 450, width: 100, height: 100)
        return ui
    }()
    
    // 动画者对象
    lazy var animator = UIDynamicAnimator(referenceView: view)
    
    override func loadView() {
        view = BGView(frame: UIScreen.main.bounds)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.addSubview(uiRedView)
        view.addSubview(uiBlueView)
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        test10()
    }
    
    /*
     * 动力学元素
     */
    func test10() -> Void {
        let gravity = UIGravityBehavior(items: [uiRedView])
        let dynamic = UIDynamicItemBehavior(items: [uiRedView])
        // 密度
        dynamic.density = 10
        // 摩擦力
        dynamic.friction = 10
        // 弹性
        dynamic.elasticity = 0.5
        
        let collision = UICollisionBehavior(items: [uiRedView])
        collision.translatesReferenceBoundsIntoBoundary = true
        
        animator.addBehavior(gravity)
        animator.addBehavior(dynamic)
        animator.addBehavior(collision)
    }
    
    /*
     * 推
     */
    func test9(_ touche: Set<UITouch>) -> Void {
        guard let point = touche.first?.location(in: view) else {
            print("point is nil")
            return
        }
        let collision = UICollisionBehavior(items: [uiRedView])
        let push = UIPushBehavior(items: [uiRedView], mode: .instantaneous)
        
        // 方向1
        // push.angle = 45
        
        // 方向2
        // push.pushDirection = CGVector(dx: 1, dy: 1)
        
        // 方向3x`
        let x = (uiRedView.center.x - point.x) / 50
        let y = (uiRedView.center.y - point.y) / 50
        push.pushDirection = CGVector(dx: x, dy: y)
        
        // 推力
        push.magnitude = 1
        
        collision.translatesReferenceBoundsIntoBoundary = true
        
        animator.addBehavior(push)
        animator.addBehavior(collision)
    }
    
    /*
     * 附着2
     */
    func test8(_ touche: Set<UITouch>) -> Void {
        let gravity = UIGravityBehavior(items: [uiRedView])
        let collision = UICollisionBehavior(items: [uiRedView,uiBlueView])
        let attach = UIAttachmentBehavior(item: uiRedView, attachedTo: uiBlueView)
        
        // 固定长度
        attach.length = 200
        // 减速程度
        attach.damping = 0.3
        attach.frequency = 10
        
        collision.translatesReferenceBoundsIntoBoundary = true
        
        animator = UIDynamicAnimator(referenceView: view)
        animator.addBehavior(attach)
        animator.addBehavior(gravity)
        animator.addBehavior(collision)
        
        attach.action = {
            let bg = self.view as! BGView
            bg.startPoint = self.uiRedView.center
            bg.finishPoint = self.uiBlueView.center
            self.view.setNeedsDisplay()
        }
    }
    
    /*
     * 附着1
     */
    func test7(_ touche: Set<UITouch>) -> Void {
        guard let point = touche.first?.location(in: view) else {
            print("point is nil")
            return
        }
        let gravity = UIGravityBehavior(items: [uiRedView])
        let attach = UIAttachmentBehavior(item: uiRedView, attachedToAnchor: point)
        // 固定长度
        attach.length = 200
        // 减速程度
        attach.damping = 0.3
        attach.frequency = 10
        
        animator = UIDynamicAnimator(referenceView: view)
        animator.addBehavior(attach)
        animator.addBehavior(gravity)
        
        attach.action = {
            let bg = self.view as! BGView
            bg.startPoint = self.uiRedView.center
            bg.finishPoint = point
            self.view.setNeedsDisplay()
        }
    }
    
    /*
     * 甩行为
     */
    func test6(_ touche: Set<UITouch>) -> Void {
        guard let point = touche.first?.location(in: view) else {
            print("point is nil")
            return
        }
        let snap = UISnapBehavior(item: uiRedView, snapTo: point)
        snap.damping = 0.2
        
        animator = UIDynamicAnimator(referenceView: view)
        animator.addBehavior(snap)
    }
    
    /*
     * 事件监听
     */
    func test5() -> Void {
        let gravity = UIGravityBehavior(items: [uiRedView])
        let collision = UICollisionBehavior(items: [uiRedView,uiBlueView])
        collision.translatesReferenceBoundsIntoBoundary = true
        collision.collisionMode = .everything
        collision.collisionDelegate = self
        // 创建边界
        collision.addBoundary(withIdentifier: "line1" as NSCopying, from: CGPoint(x: 150, y: 240), to: CGPoint(x: 300, y: 300))
        collision.addBoundary(withIdentifier: "line2" as NSCopying, for: UIBezierPath(rect: uiBlueView.frame))
        
        collision.action = {
            let bgView = self.view as! BGView
            bgView.mRedViewPath = self.uiRedView
            bgView.mBlueViewPath = self.uiBlueView
            self.view.setNeedsDisplay()
        }
        
        animator.addBehavior(gravity)
        animator.addBehavior(collision)
    }
    
    func collisionBehavior(_ behavior: UICollisionBehavior, endedContactFor item: UIDynamicItem, withBoundaryIdentifier identifier: NSCopying?) {
        guard let str = identifier as? String else {
            return
        }
        print("identifier=\(str)")
        if str.elementsEqual("line1") {
            uiRedView.backgroundColor = UIColor.purple
        }else {
            uiRedView.backgroundColor = UIColor.red
        }
        
        if str.elementsEqual("line2") {
            uiBlueView.backgroundColor = UIColor.green
        }else {
            uiBlueView.backgroundColor = UIColor.blue
        }
    }
    
    /*
     * 边界、动作监听
     */
    func test4() -> Void {
        let gravity = UIGravityBehavior(items: [uiRedView])
        let collision = UICollisionBehavior(items: [uiRedView,uiBlueView])
        collision.translatesReferenceBoundsIntoBoundary = true
        collision.collisionMode = .everything
        
        // 创建边界
        collision.addBoundary(withIdentifier: "line1" as NSCopying, from: CGPoint(x: 150, y: 240), to: CGPoint(x: 300, y: 300))
        collision.addBoundary(withIdentifier: "line2" as NSCopying, for: UIBezierPath(rect: uiBlueView.frame))
        
        collision.action = {
            let bgView = self.view as! BGView
            bgView.mRedViewPath = self.uiRedView
            bgView.mBlueViewPath = self.uiBlueView
            self.view.setNeedsDisplay()
        }
        
        animator.addBehavior(gravity)
        animator.addBehavior(collision)
    }
    
    /*
     * 边界、动作监听
     */
    func test3() -> Void {
        // 创建重力行为
        let gravity = UIGravityBehavior(items: [uiRedView,uiBlueView])
        // 创建碰撞行为
        let collision = UICollisionBehavior(items: [uiRedView])
        // 把引用view的bounds设置为边界
        collision.translatesReferenceBoundsIntoBoundary = true
        collision.collisionMode = .boundaries
        
        // 创建边界
        collision.addBoundary(withIdentifier: "line1" as NSCopying, from: CGPoint(x: 150, y: 240), to: CGPoint(x: 300, y: 300))
        
        // 边界实施监听
        collision.action = {
            if self.uiRedView.frame.width > 130 {
                self.uiRedView.backgroundColor = UIColor.orange
            }else {
                self.uiRedView.backgroundColor = UIColor.red
            }
            
            let bgView = self.view as! BGView
            bgView.mRedViewPath = self.uiRedView
            self.view.setNeedsDisplay()
        }
        
        animator.addBehavior(gravity)
        animator.addBehavior(collision)
    }
    
    /*
     * 碰撞
     */
    func test2() -> Void {
        // 创建重力行为
        let gravity = UIGravityBehavior(items: [uiRedView,uiBlueView])
        // 创建碰撞行为
        let collision = UICollisionBehavior(items: [uiRedView])
        // 把引用view的bounds设置为边界
        collision.translatesReferenceBoundsIntoBoundary = true
        
        animator.addBehavior(gravity)
        animator.addBehavior(collision)
    }
    
    /*
     * 重力
     */
    func test1() -> Void {
        // 重力行为
        let gravity = UIGravityBehavior(items: [uiRedView])
        // 方向1
        // gravity.gravityDirection = CGVector(dx: 1, dy: 1)
        
        // 方向2
        // gravity.angle = 45
        
        // 重力量级
        gravity.magnitude = 10
        
        animator.addBehavior(gravity)
    }
}

class BGView: UIView {
    
    var mRedViewPath:UIView?
    var mBlueViewPath:UIView?
    
    var startPoint:CGPoint?
    var finishPoint:CGPoint?
    
    override func draw(_ rect: CGRect) {
        // 边界线
        let path = UIBezierPath()
        path.move(to: CGPoint(x: 150, y: 240))
        path.addLine(to: CGPoint(x: 300, y: 300))
        UIColor.black.setStroke()
        path.stroke()
        
        // view的边界线
        if let uRedPath = mRedViewPath {
            UIBezierPath(rect: uRedPath.frame).stroke()
        }
        if let uBluePath = mBlueViewPath {
            let bluePath = UIBezierPath(rect: uBluePath.frame)
            bluePath.lineWidth = 5
            UIColor.red.setStroke()
            bluePath.stroke()
        }
        
        // 连接线
        if let start = startPoint,let finish = finishPoint {
            let line = UIBezierPath()
            line.move(to: start)
            line.addLine(to: finish)
            line.stroke()
        }
    }
}
